/*
 * @Description: 聊天室 - 聊天页面
 * @Author: Yong
 * @Date: 2021-10-08 20:39:26
 * @LastEditTime: 2021-10-10 22:35:43
 */

import { Context, Application as SocketApplication } from '@midwayjs/socketio'
import { App, Provide, Inject, OnWSConnection, WSController, OnWSDisConnection, OnWSMessage, MidwayFrameworkType } from '@midwayjs/decorator'
import { FriendsService } from '../service/Friends'
import { MessageService } from '../service/Message'

const user: { [k: string]: any } = {}


@Provide()
@WSController('/chatRoom')
export class ChatRoomSocketController {
    @Inject()
    ctx: Context

    @App(MidwayFrameworkType.WS_IO)
    socketApp: SocketApplication;

    @Inject()
    friendsService: FriendsService

    @Inject()
    messageService: MessageService

    // socket 注册用户 { 用户ID: socket.id, .... }
    userID: string = null

    // 监听用户连接
    @OnWSConnection()
    async onConnection () {
        console.log('chatRoom客户端连接成功, socketId ==> ', this.ctx.id)
        // 获取当前登录用户的userID
        const userID = this.ctx.handshake.query.userID
        const friendID = this.ctx.handshake.query.friendID
        this.userID = userID.toString()
        user[userID.toString()] = this.ctx.id
        console.log('chatRoom客户端连接成功, user ==> ', user)
        // 更新所有未读消息为已读
        await this.messageService.updateMsgState(userID.toString(), friendID.toString())
    }

    // 监听用户离开
    @OnWSDisConnection()
    async disConnection () {
        console.log('user==>', user)        
        if (user.hasOwnProperty(this.userID)) {
            delete user[this.userID]
            this.userID = null
            console.log(`${this.ctx.id}离开`)
            console.log('chatRoom客户端断开, user ==> ', user)
        }
    }

    // 接收客户端发送的消息
    @OnWSMessage('msg')
    async getMessage (msg, uid, fid) {
        // 消息对象
        const msgInfo = {
            uid: uid,
            fid: fid,
            cont: msg.cont,
            type: msg.type,
            // 如果对方在线则表示已读消息 - 离线表示未读消息
            state: user[fid] ? 0 : 1
        }
        // 添加一对一消息
        await this.messageService.addMessage(msgInfo)
        // 更新好友表的最新时间
        await this.friendsService.updateLastTimeBy(uid, fid)

        // 接收后发送给对应的fid客户端 - msg/消息 fromId/来自那个uid用户 toId/发送到那个用户fid
        // 如果对方在线则发送 否则只存入数据库
        if (user[fid]) {
            this.ctx.nsp.to(user[fid]).emit("msg", msg, uid)
        }

        // 更新好友的home端 - 好友消息列表
        const friendMsgList = (await this.friendsService.getFriends(fid.toString(), 0))
        this.socketApp.of('/home').emit('updateFriendMsgList', { friendMsgList: friendMsgList, toId: fid })
    }
}